home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
xinu.arc
/
XINU1.C
< prev
next >
Wrap
Text File
|
1986-01-03
|
24KB
|
905 lines
/* dscntl.c - dscntl p. 300 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dscntl -- control disk driver / device
*-----------------------------------------------------------------------------
*/
dscntl(devptr, func)
struct devsw *devptr;
{
int stat;
char ps;
disable(ps);
switch(func) {
case DSKSYNC:
stat = dsksync(devptr);
break;
default:
stat = SYSERR;
break;
}
restore(ps);
return(stat);
}
/* dskstrt.c - dskstrt p. 290 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dskstrt -- start an I/O operation on a disk device
*-----------------------------------------------------------------------------
*/
dskstrt(dsptr)
struct dsblk *dsptr;
{
struct xbdcb *xptr;
struct dtc *dtptr;
struct dreq *drptr;
/* build command for controller */
drptr = dsptr->dreqlst;
xptr = &dsptr->ddcb;
xptr->xop = (char) drptr->drop; /* opcode */
xptr->xunit = (char) 0; /* top address bits */
xptr->xmaddr = (char) ((drptr->drdba>>8)&0377); /* middle addr bits */
xptr->xladdr = (char) (drptr->drdba & 0377); /* low address bits */
xptr->xcount = (char) 1; /* number of blocks */
xptr->xcntl = (char) XRETRY; /* retry code */
/* feed command to controller through interface */
dtptr = dsptr->dcsr;
dtptr->dt_dar = drptr->drbuff;
dtptr->dt_car = xptr;
dtptr->dt_xdar = dtptr->dt_xcar = 0;
dtptr->dt_csr = DTINTR | DTGO;
}
/* dsseek.c - dsseek p. 297 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dsseek -- schedule a request to move the disk arm
*-----------------------------------------------------------------------------
*/
dsseek(devptr, block)
struct devsw *devptr;
DBADDR block;
{
struct dreq *drptr;
char ps;
disable(ps);
drptr = (struct dreq *) getbuf(dskrbp);
drptr->drdba = block;
drptr->drpid = currpid;
drptr->drbuff = NULL;
drptr->drop = DSEEK;
/* enqueued with normal policy like other read/write requests */
dskenq(drptr,devptr->dvioblk);
restore(ps);
return(OK);
}
/* dsinit.c - dsinit p. 291 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# ifdef Ndsk
struct dsblk dstab[Ndsk];
# endif
int dskdbp, dskrbp;
/*-----------------------------------------------------------------------------
* dsinit -- initialize disk drive device
*-----------------------------------------------------------------------------
*/
dsinit(devptr)
struct devsw *devptr;
{
struct dsblk *dsptr;
struct dtc *dtptr;
int status;
char ps;
disable(ps);
devptr->dvioblk = dsptr = &dstab[devptr->dvminor];
dsptr->dcsr = devptr->dvcsr;
dsptr->dreqlst = DRNULL;
dsptr->dnum = devptr->dvnum;
dsptr->dibsem = screate(1);
dsptr->dflsem = screate(1);
dsptr->ddirsem = screate(1);
dsptr->dnfiles = 0;
dsptr->ddir = getbuf(dskdbp);
iosetvec(devptr->dvnum, dsptr, dsptr);
/* read directory block; setup read command then start interface */
dsptr->ddcb.xop = (char) XOREAD;
dsptr->ddcb.xunit = (char) 0;
dsptr->ddcb.xcntl = (char) XRETRY;
dsptr->ddcb.xmaddr = (char) ((DIRBLK>>8)&(0377));
dsptr->ddcb.xladdr = (char) (DIRBLK & 0377);
dsptr->ddcb.xcount = (char) 1;
dtptr = dsptr->dcsr;
dtptr->dt_dar = dsptr->ddir;
dtptr->dt_car = &dsptr->ddcb;
dtptr->dt_xdar = dtptr->dt_xcar = NULL;
dtptr->dt_csr = DTGO;
while (((status=dtptr->dt_csr) & DTDONE) == 0)
;
if (status & DTERROR)
panic("disk error");
restore(ps);
return(OK);
}
/* dsksync.c - dsksync p. 300 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dsksync -- wait for all outstanding disk requests before returning
*-----------------------------------------------------------------------------
*/
dsksync(devptr)
struct devsw *devptr;
{
struct dreq *drptr, *p, *q;
int stat;
if ((q=(devptr->dvioblk)->dreqlst) == DRNULL)
return(OK);
drptr = (struct dreq *) getbuf(dskrbp);
drptr->drdba = 0;
drptr->drpid = currpid;
drptr->drbuff = NULL;
drptr->drop = DSYNC;
drptr->drnext = DRNULL;
/* place at end of request list */
for (p=q->drnext ; p!=DRNULL ; q=p,p=p->drnext)
;
q->drnext = drptr;
drptr->drstat = SYSERR;
suspend(currpid);
stat = drptr->drstat;
freebuf(drptr);
return(stat);
}
/* dswrite.c - dswrite p. 296 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dswrite -- write a block ( system buffer ) onto a disk device
*-----------------------------------------------------------------------------
*/
dswrite(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
struct dreq *drptr;
char ps;
disable(ps);
drptr = (struct dreq *) getbuf(dskrbp);
drptr->drbuff = buff;
drptr->drdba = block;
drptr->drpid = currpid;
drptr->drop = DWRITE;
dskenq(drptr,devptr->dvioblk);
restore(ps);
return(OK);
}
/* chprio.c - chprio p. 76 */
#include <conf.h>
#include <kernel.h>
#include <proc.h>
/*-----------------------------------------------------------------------------
* chprio -- change the scheduling priority of a process
*-----------------------------------------------------------------------------
*/
SYSCALL chprio(pid,newprio)
int pid;
int newprio; /* newprio > 0 */
{
int oldprio;
struct pentry *pptr;
char ps;
disable(ps);
if (isbadpid(pid) || newprio<=0 ||
(pptr = &proctab[pid])->pstate == PRFREE) {
restore(ps);
return(SYSERR);
}
oldprio = pptr->pprio;
pptr->pprio = newprio;
switch( pptr->pstate) {
case PRCURR : /*
* The process is already running. so just change
* the priority. We reschedule the system if the
* new priority is less than the old priority.
* We don't have to reschedule if the priority is
* greater : we are already the greatest priority
* process running. But, if the priority is less
* we just might be smaller than some other process
*/
if( oldprio > newprio ) resched();
break;
case PRREADY: /*
* In this case the process is on the ready queue.
* We first need to take it off the ready queue. We
* than change the priority, and place it back. The
* last step is to run resched, just in case. The
* real check should be to see if newprio is bigger
* than the priority of the current running process.
* If it is, we should can resched. The reason we
* don't do it is because if resched every changes
* we would have to go back and 'fix' everything.
*/
dequeue(pid);
insert(pid,rdyhead,newprio);
resched();
break;
case PRRECV :
case PRSLEEP:
case PRSUSP :
case PRWAIT : /*
* In these cases the process is not on the ready
* queue. So we only need to change the priority
* and exit.
*/
break;
default : /* if we get here, the system is corrupted */
restore(ps);
return(SYSERR);
}
restore(ps);
return(oldprio);
}
/* create.c - create, newpid p. 74 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <mem.h>
/*-----------------------------------------------------------------------------
* create -- create a process to start running a procedure
*-----------------------------------------------------------------------------
*/
SYSCALL create(procaddr,ssize,priority,name,nargs,args)
int *procaddr; /* procedure address */
int ssize; /* stack size in words */
int priority; /* process priority >= 0 */
char *name; /* name ( for debugging ) */
int nargs; /* number of args that follow */
int args; /* arguments (treated like an array) */
{
int pid; /* stores new process id */
struct pentry *pptr; /* pointer to process table entry */
int i;
int *a; /* points to list of arguments */
int *saddr; /* stack address */
char ps; /* saved processor status */
int INITRET();
disable(ps);
ssize = roundew(ssize);
if ( ssize < MINSTK || ((saddr=getstk(ssize)) == SYSERR ) ||
(pid=newpid()) == SYSERR || isodd(procaddr) ||
priority < 1 ) {
restore(ps);
return(SYSERR);
}
numproc++;
pptr = &proctab[pid];
pptr->pstate = PRSUSP;
for (i=0; i<PNMLEN && (pptr->pname[i]=name[i])!=0; i++)
;
pptr->pprio = priority;
pptr->pbase = (short)saddr;
pptr->pstklen = ssize;
pptr->plimit = (short) ( saddr - ssize + 1);
pptr->pargs = nargs;
for (i=0; i<PNREGS; i++)
pptr->pregs[i] = INITREG;
pptr->pregs[PC] = pptr->paddr = (short)procaddr;
pptr->pregs[PS] = INITPS;
a = (&args) + (nargs-1); /* point to last argument */
for ( ; nargs>0; nargs--) /* machine dependent, copy args */
*saddr-- = *a--; /* onto created process' stack */
*saddr = (int)INITRET; /* push on return address */
pptr->pregs[SP] = (int)saddr;
restore(ps);
return(pid);
}
/*-----------------------------------------------------------------------------
* newpid -- obtain a new ( free ) process id
*-----------------------------------------------------------------------------
*/
LOCAL newpid()
{
int pid; /* process id to return */
int i;
for (i=0; i<NPROC; i++) { /* check all NPROC slots */
if ((pid=nextproc--) <= 0)
nextproc = NPROC-1;
if (proctab[pid].pstate == PRFREE)
return(pid);
}
return(SYSERR);
}
/* getbuf.c - getbuf p. 236 */
#include <conf.h>
#include <kernel.h>
#include <mark.h>
#include <bufpool.h>
/*-----------------------------------------------------------------------------
* getbuf -- get a buffer from a preestablished buffer pool
*-----------------------------------------------------------------------------
*/
int *
getbuf(poolid)
int poolid;
{
char ps;
int *buf;
#ifdef MEMMARK
if (unmarked(bpmark))
return((int *)SYSERR);
#endif
if (poolid<0 || poolid>=nbpools)
return((int *)SYSERR);
wait(bptab[poolid].bpsem);
disable(ps);
buf = bptab[poolid].bpnext;
bptab[poolid].bpnext = *buf;
restore(ps);
*buf++ = poolid;
return(buf);
}
/* getpid.c - getpid p. 77 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
/*-----------------------------------------------------------------------------
* getpid -- get the process id of currently executing process
*-----------------------------------------------------------------------------
*/
SYSCALL getpid()
{
return(currpid);
}
/* iblfree.c - iblfree p. 316 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* iblfree -- free a list of iblocks given the number of the first
*-----------------------------------------------------------------------------
*/
iblfree(diskdev, iblist)
int diskdev;
IBADDR iblist;
{
IBADDR ilast;
struct iblk iblock;
struct dir *dirptr;
int sem;
DBADDR dba;
int j;
if (iblist == IBNULL)
return(OK);
dirptr = dsdirec(diskdev);
ibget(diskdev, iblist, &iblock);
for (ilast=iblist ; iblock.ib_next!=IBNULL ; ) {
for (j=0 ; j<IBLEN ; j++)
if ((dba=iblock.ib_dba[j]) != DBNULL)
lfsdfree(diskdev, dba);
ilast = iblock.ib_next;
ibget(diskdev, ilast, &iblock);
}
for (j=0 ; j<IBLEN ; j++)
if ((dba=iblock.ib_dba[j]) != DBNULL)
lfsdfree(diskdev, dba);
sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
wait(sem);
iblock.ib_next = dirptr->d_filst;
dirptr->d_filst = iblist;
ibput(diskdev, ilast, &iblock);
write(diskdev, dskbcpy(dirptr), DIRBLK);
signal(sem);
return(OK);
}
/* ioinit.c - ioinit, iosetvec p. 154 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* ioinit -- standard interrupt vector and dispatch initialization
*-----------------------------------------------------------------------------
*/
ioinit(descrp)
int descrp;
{
int minor;
if (isbaddev(descrp))
return(SYSERR);
minor = devtab[descrp].dvminor;
iosetvec(descrp, minor, minor);
return(OK);
}
/*-----------------------------------------------------------------------------
* iosetvec -- fill in interrupt vectors and dispatch table entries
*-----------------------------------------------------------------------------
*/
iosetvec(descrp, incode, outcode)
int descrp;
int incode;
int outcode;
{
struct devsw *devptr;
struct intmap *map;
struct vector *vptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
map = &intmap[devptr->dvnum]; /* fill in tnterrupt dispatch map */
map->iin = devptr->dviint; /* with addresses of high-level */
map->icode = incode; /* input and output interrupt */
map->iout = devptr->dvoint; /* handlers and minor device */
map->ocode = outcode; /* numbers */
vptr = (struct vector *)devptr->dvivec;
vptr->vproc = (char *)INTVECI; /* fill in input interrupt vector PC */
vptr->vps = descrp | DISABLE; /* and PS values */
vptr = (struct vector *)devptr->dvovec;
vptr->vproc = (char *)INTVECO; /* fill in output interrupt vector */
vptr->vps = descrp | DISABLE; /* PC and PS values */
return(OK);
}
/* lfclose.c - lfclose p. 339 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
# include <file.h>
/*-----------------------------------------------------------------------------
* lfclose -- close a file by flushing output and freeing device slot
*-----------------------------------------------------------------------------
*/
lfclose(devptr)
struct devsw *devptr;
{
struct dsblk *dsptr;
struct dir *dirptr;
struct flblk *flptr;
int diskdev;
char ps;
disable(ps);
flptr = (struct flblk *)devptr->dvioblk;
if (flptr->fl_pid != currpid) {
restore(ps);
return(SYSERR);
}
diskdev = flptr->fl_dev;
dsptr = (struct dsblk *)devtab[diskdev].dvioblk;
dirptr = (struct dir *)dsptr->ddir;
if ((flptr->fl_mode&FLWRITE) && flptr->fl_dch)
lfsflush(flptr);
flptr->fl_pid = 0;
dsptr->dnfiles--;
write(diskdev, dskbcpy(dirptr), DIRBLK);
restore(ps);
return(OK);
}
/* lfread.c - lfread p. 337 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*----------------------------------------------------------------------------
* lfread -- read from a previously opened disk file
*----------------------------------------------------------------------------
*/
lfread(devptr, buff, count)
struct devsw *devptr;
char *buff;
int count;
{
int done;
int ichar;
if (count < 0)
return(SYSERR);
for (done = 0; done < count; done++)
if ( (ichar = lfgetc(devptr)) == SYSERR)
return(SYSERR);
else if (ichar == EOF) { /* EOF before finished */
if (done == 0)
return(EOF);
else
return(done);
} else
*buff++ = (char)ichar;
return(done);
}
/* lfsflush.c - lfsflush p. 330 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfsflush -- flush data and i-block for a file
*-----------------------------------------------------------------------------
*/
lfsflush(flptr)
struct flblk *flptr;
{
DBADDR dba;
if (!flptr->fl_dch)
return(SYSERR);
dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum];
write(flptr->fl_dev, dskbcpy(flptr->fl_buff), dba);
flptr->fl_dch = FALSE;
return ( OK );
}
/* close.c - close p. 149 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* close -- close a device
*-----------------------------------------------------------------------------
*/
close(descrp)
int descrp;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvclose)(devptr));
}
/* dfalloc.c - dfalloc p. 325 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
/*-----------------------------------------------------------------------------
* dfalloc -- allocate a device table entry for a disk file; return id
*-----------------------------------------------------------------------------
*/
dfalloc()
{
int i;
for (i=0 ; i<Ndf ; i++)
if (fltab[i].fl_pid == 0) {
fltab[i].fl_pid = getpid();
return(i);
}
return(SYSERR);
}
/* getc.c - getc p. 146 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* getc -- get one character from a device
*-----------------------------------------------------------------------------
*/
getc(descrp)
int descrp;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvgetc)(devptr));
}
/* getstk.c - getstk p. 108 */
# include <conf.h>
# include <kernel.h>
# include <mem.h>
/*-----------------------------------------------------------------------------
* getstk -- allocate stack memory, returning address of topmost int
*-----------------------------------------------------------------------------
*/
int *getstk(nbytes)
unsigned int nbytes;
{
char ps;
struct mblock *p, *q; /* q follows p along memlist */
struct mblock *fits, *fitsq;
int len;
disable(ps);
if (nbytes == 0) {
restore(ps);
return((int *)SYSERR);
}
nbytes = (unsigned int) roundew(nbytes);
fits = NULL;
q = &memlist;
for (p = q->mnext ; p != NULL ; q = p, p = p->mnext)
if ( p->mlen >= nbytes ) {
fitsq = q;
fits = p;
}
if (fits == NULL) {
restore(ps);
return((int *)SYSERR);
}
if (nbytes == fits->mlen) {
fitsq->mnext = fits->mnext;
len = nbytes;
} else {
len = fits->mlen;
fits->mlen -= nbytes;
}
fits = ((int)fits) + len - sizeof(int);
*((int *)fits) = nbytes;
restore(ps);
return((int *)fits);
}
/* ibnew.c - ibnew p. 314 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* ibnew -- allocate a new iblock from free list on disk
*-----------------------------------------------------------------------------
*/
ibnew(diskdev, writedir)
int diskdev;
Bool writedir;
{
struct dir *dirptr;
struct iblk iblock;
IBADDR inum;
int i;
int sem;
sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
dirptr = dsdirec(diskdev);
wait(sem);
inum = dirptr->d_filst;
ibget(diskdev, inum, &iblock);
dirptr->d_filst = iblock.ib_next;
if (writedir)
write(diskdev, dskbcpy(dirptr), DIRBLK);
signal(sem);
ibclear(&iblock, 0L);
ibput(diskdev, inum, &iblock);
return(inum);
}
/* insert.c - insert p. 48 */
# include <conf.h>
# include <kernel.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* insert.c -- insert a process into a q list in key order
*-----------------------------------------------------------------------------
*/
int insert(proc, head, key)
int proc; /* process to insert */
int head; /* q index of head of list */
int key; /* key to use for this process */
{
int next; /* runs through list */
int prev;
next = q[head].qnext;
while (q[next].qkey < key) /* tail has MAXINT as key */
next = q[next].qnext;
q[proc].qnext = next;
q[proc].qprev = prev = q[next].qprev;
q[proc].qkey = key;
q[prev].qnext = proc;
q[next].qprev = proc;
return(OK);
}
/* ionull.c - ionull p. 151 */
# include <conf.h>
# include <kernel.h>
/*-----------------------------------------------------------------------------
* ionull -- do nothing (used for "don't care" entries in devtab)
*-----------------------------------------------------------------------------
*/
ionull()
{
return(OK);
}
/* lfgetc.c - lfgetc p. 334 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfgetc -- get next character from (buffered) disk file
*-----------------------------------------------------------------------------
*/
lfgetc(devptr)
struct devsw *devptr;
{
struct flblk *flptr;
char nextch;
char ps;
disable(ps);
flptr = (struct flblk *)devptr->dvioblk;
if (flptr->fl_pid!=currpid || !(flptr->fl_mode&FLREAD)) {
restore(ps);
return(SYSERR);
}
if (flptr->fl_pos >= (flptr->fl_dent)->fdlen) {
restore(ps);
return(EOF);
}
if (flptr->fl_bptr >= &flptr->fl_buff[DBUFSIZ]) {
if (flptr->fl_dch)
lfsflush(flptr);
lfsetup(flptr->fl_dev, flptr);
}
nextch = *(flptr->fl_bptr)++;
flptr->fl_pos++;
restore(ps);
return(nextch);
}
/* lfsdfree.c - lfsdfree p. 329 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfsdfree -- free a data block given its address
*-----------------------------------------------------------------------------
*/
lfsdfree(diskdev, dba)
int diskdev;
DBADDR dba;
{
struct dir *dirptr;
int dirsem;
struct freeblk *buf;
dirptr = dsdirec(diskdev);
dirsem = devtab[diskdev].dvioblk->dflsem;
buf = (struct freeblk *)getbuf(dskdbp);
wait(dirsem);
buf->fbnext = dirptr->d_fblst;
dirptr->d_fblst = dba;
write(diskdev, buf, dba);
write(diskdev, dskbcpy(dirptr), DIRBLK);
signal(dirsem);
return(OK);
}
/* lfsnewd.c - lfsnewd p. 328 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
# define DFILLER '+'
/*-----------------------------------------------------------------------------
* lfsnewd -- allocate a new data block from free list on disk
*-----------------------------------------------------------------------------
*/
lfsnewd(diskdev, flptr)
int diskdev;
struct flblk *flptr;
{
struct iblock *ibptr;
struct dir *dirptr;
struct freeblk *fbptr;
char *buf;
int sem;
DBADDR dba;
int i;
dirptr = dsdirec(diskdev);
fbptr = (struct freeblk *)(buf = flptr->fl_buff);
sem = ((struct dsblk *)devtab[diskdev].dvioblk)->dflsem;
wait(sem);
dba = dirptr->d_fblst;
read(diskdev, fbptr, dba);
dirptr->d_fblst = fbptr->fbnext;
write(diskdev, dskbcpy(dirptr), DIRBLK);
signal(sem);
for (i=0 ; i<DBUFSIZ ; i++)
*buf++ = DFILLER;
write(diskdev, dskbcpy(fbptr), dba);
return(dba);
}